/*
 * Copyright (c) 2010-2011 Josef Hardi <josef.hardi@gmail.com>
 * Copyright (c) 2010 Piotr Zagawa <piotr.zagawa@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package id.duapuluhdua.dakidaki.loader;

import java.util.ArrayList;
import java.util.HashMap;

import id.duapuluhdua.dakidaki.map.GeoPoint;

/**
 *
 */
public class DataStatsTrackCollection
{
  /** Constants */
  private final Boolean bMapMutex = false;

  /** Fields */
  // Track items: key - track_id
  private HashMap<Long,TrackPointsData> mMapTracksPoints = new HashMap<Long,TrackPointsData>();

  // methods
  private TrackPointsData getTrackPoints(TrackItem trackItem)
  {
    final Long trackId = trackItem.getId();

    TrackPointsData data = null;

    synchronized (bMapMutex)
    {
      // get track points data, create one if not exists
      data = mMapTracksPoints.get(trackId);
      if (data == null) {
        data = new TrackPointsData(trackItem);
        mMapTracksPoints.put(trackId, data);
      }
      else {
        data.setPoints(trackItem);
      }
    }
    return data;
  }

  protected GeoPoint getNearestPoint(GeoPoint location, TrackItem trackItem)
  {
    if (trackItem != null) {
      final TrackPointsData data = getTrackPoints(trackItem);
      if (data != null) {
        return getNearestPoint(location, data);
      }
    }
    return null;
  }

  private GeoPoint getNearestPoint(GeoPoint location, TrackPointsData data)
  {
    GeoPoint targetPoint = null;

    if (location == null) {
      return null;
    }
    // thousand km
    double maxDistance = 1000 * 1000;

    synchronized (bMapMutex)
    {
      if (data == null) {
        return null;
      }
      if (data.points.isEmpty()) {
        return null;
      }
      if (data.points.size() > 0) {
        targetPoint = data.points.get(0);
      }

      for (GeoPoint point : data.points) {
        final double dDistance = location.distance(point);

        if (dDistance < maxDistance) {
          targetPoint = point;
          maxDistance = dDistance;
        }
      }
    }
    return targetPoint;
  }

  // track data item
  private class TrackPointsData
  {
    public ArrayList<GeoPoint> points = null;

    public TrackPointsData(TrackItem item)
    {
      setPoints(item);
    }

    public void setPoints(TrackItem item)
    {
      // get points copy
      if (points == null) {
        points = item.clonePoints();
      }
      else {
        // get new points copy each time
        if (!item.isClosed()) {
          points = item.clonePoints();
        }
      }
    }
  };
}
